package com.cndw.kungfu.socket;

import java.io.IOException;
import java.util.UUID;

import message.push.util.Aes;
import message.push.util.TimeProcesser;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBufferOutputStream;
import org.jboss.netty.buffer.ChannelBuffers;

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Output;

/**
 * socket 璇锋眰瀵硅薄
 * 
 * 
 * @author <a href="mailto:whz-work@163.com">姹椽宸�/a>
 * 
 * @since 1.0 Create on 2011-5-18
 */
public class SocketRequest {

	/**
	 * 璇锋眰搴忓垪鍙�
	 */
	private String requestId;
	/**
	 * 璇锋眰鏈嶅姟鍣╥d
	 */
	private Integer serverId;
	/**
	 * 璇锋眰鍙傛暟
	 */
	private Object[] parameters;

	/**
	 * 鎺у埗鍣ㄥ悕瀛�
	 */
	private String controllerName;

	/**
	 * 鎺у埗鍣ㄧ殑鏂规硶
	 */
	private String controllerMethod;

	/**
	 * amf3搴忓垪鍖栦笂涓嬫枃
	 */
	public static SerializationContext context = SerializationContext.getSerializationContext();

	public SocketRequest(Integer serverId, String controllerName, String controllerMethod) {
		this(serverId, controllerName, controllerMethod, new Object[] {});
	}

	public SocketRequest(Integer serverId, String controllerName, String controllerMethod, Object... parameters) {
		this.serverId = serverId;
		this.parameters = parameters;
		this.requestId = UUID.randomUUID().toString();
		this.controllerName = controllerName;
		this.controllerMethod = controllerMethod;
	}

	/**
	 * 鑾峰彇璇锋眰澶�cndw寮�ご)
	 * 
	 * @return
	 */
	protected ChannelBuffer setRequestHeader(ChannelBuffer buffer) {
		ChannelBuffer request = ChannelBuffers.buffer(buffer.readableBytes() + 8);
		request.writeBytes(new byte[] { 99, 110, 100, 119 });
		request.writeInt(buffer.readableBytes());
		request.writeBytes(buffer);
		return request;
	}

	/**
	 * 搴忓垪鍖栬姹傚璞�
	 * 
	 * @return
	 */
	public ChannelBuffer serialize() {
		ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
		ChannelBufferOutputStream outputStream = new ChannelBufferOutputStream(buffer);
		Amf3Output output = new Amf3Output(context);
		output.setOutputStream(outputStream);

		try {
			output.writeObject(getControllerName());
			output.writeObject(getControllerMethod());
			output.writeObject(getRequestId());
			output.writeObject(getCipher());
			for (Object parameter : parameters) {
				output.writeObject(parameter);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return setRequestHeader(buffer);
	}

	public String getRequestId() {
		return requestId;
	}

	public Object[] getParameters() {
		return parameters;
	}

	public String getControllerName() {
		return controllerName;
	}

	public String getControllerMethod() {
		return controllerMethod;
	}

	public Integer getServerId() {
		return serverId;
	}

	public String getCipher() {
		return encryptRequest(getControllerName(), getControllerMethod());
	}

	private static String encryptRequest(String... params) {
		StringBuilder param = new StringBuilder();
		for (String p : params) {
			param.append(p);
			param.append("\r\n");
		}
		param.append(TimeProcesser.getUnixTime());
		return Aes.encrypt(param.toString());
	}
}
